home *** CD-ROM | disk | FTP | other *** search
- /* _Fmtval function */
- #include <limits.h>
- #include <locale.h>
- #include <stdio.h>
- #include <string.h>
-
-
- /* macros */
- #define FN_INT_CUR -2
- #define FN_LCL_CUR -1
-
-
- char *_Fmtval(char *buf, double d, int fdarg)
- { /* format number by locale-specific rules */
- char *cur_sym, dec_pt, *grps, grp_sep, *sign;
- const char *fmt;
- int fd, neg;
- struct lconv *p = localeconv();
-
-
- if (0 <= d)
- neg = 0;
- else
- d = -d, neg = 1;
- if (fdarg == FN_INT_CUR)
- { /* get international currency parameters */
- cur_sym = p->int_curr_symbol;
- dec_pt = p->mon_decimal_point[0];
- fmt = "$-V";
- fd = p->int_frac_digits;
- grps = p->mon_grouping;
- grp_sep = p->mon_thousands_sep[0];
- sign = neg ? p->negative_sign : p->positive_sign;
- }
- else if (fdarg == FN_LCL_CUR)
- { /* get local currency parameters */
- static const char *ftab[5][2][2] = {
- "(V$)", "-V$", "V$-", "V-$", "V$-",
- "($V)", "-$V", "$V-", "-$V", "$-V",
- "(V $)", "-V $", "V $-", "V- $", "V $-",
- "($ V)", "-$ V", "$ V-", "-$ V", "$ -V"};
-
-
- cur_sym = p->currency_symbol;
- dec_pt = p->mon_decimal_point[0];
- if (neg)
- fmt = ftab[p->n_sign_posn < 0 || 4 < p->n_sign_posn
- ? 0 : p->n_sign_posn][p->n_cs_precedes == 1]
- [p->n_sep_by_space == 1];
- else
- fmt = ftab[p->p_sign_posn < 0 || 4 < p->p_sign_posn
- ? 0 : p->p_sign_posn][p->p_cs_precedes == 1]
- [p->p_sep_by_space == 1];
- fd = p->frac_digits;
- grps = p->mon_grouping;
- grp_sep = p->mon_thousands_sep[0];
- sign = neg ? p->negative_sign : p->positive_sign;
- }
- else
- { /* get numeric parameters (cur_sym not used) */
- dec_pt = p->decimal_point[0];
- fmt = "-V";
- fd = fdarg;
- grps = p->grouping;
- grp_sep = p->thousands_sep[0];
- sign = neg ? "-" : "";
- }
- { /* build string in buf under control of fmt */
- char *end, *s;
- const char *g;
- size_t i, ns;
-
-
- for (s = buf; *fmt; ++fmt, s += strlen(s))
- switch (*fmt)
- { /* process a format char */
- case '$': /* insert currency symbol string */
- strcpy(s, cur_sym);
- break;
- case '-': /* insert sign string */
- strcpy(s, sign);
- break;
- default: /* insert literal format char */
- *s++ = *fmt, *s = '\0';
- break;
- case 'V': /* insert formatted value */
- sprintf(s, "%#.*f",
- 0 < fd && fd != CHAR_MAX ? fd : 0, d);
- end = strchr(s, p->decimal_point[0]);
- for (ns = 0, i = end - s, g = grps; 0 < i; ++ns)
- { /* count separators to add */
- if (g[0] <= 0 || i <= g[0] || g[0] == CHAR_MAX)
- break;
- i -= g[0];
- if (g[1] != 0)
- ++g;
- }
- memmove(end + ns, end, strlen(end) + 1);
- i = end - s, end += ns;
- *end = 0 <= fd && fd != CHAR_MAX ? dec_pt : '\0';
- for (g = grps; 0 < i; --ns)
- { /* copy up and insert separators */
- if (g[0] <= 0 || i <= g[0] || g[0] == CHAR_MAX)
- break;
- i -= g[0], end -= g[0];
- memmove(end, end - ns, g[0]);
- *--end = grp_sep;
- if (g[1] != 0)
- ++g;
- }
- }
- }
- return (buf);
- - }
-
-
-
-
-